package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"image/color"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"unicode/utf8"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
	"github.com/flopp/go-findfont"
	"github.com/goki/freetype/truetype"
)

// 应用状态
type AppState struct {
	openId               string
	nickName             string
	isLogin              bool
	isDoLogin            bool
	isDoUploadBook       bool
	isDoManageBook       bool
	isDoLeaveMsg         bool
	pubBooks             []Book
	myBooks              []Book
	myLeaveMsgs          []LeaveMsg
	listSelectId         int
	myBookListLen        int
	bookSelectId         int64
	bookSelectOpenId     string
	pubBookSelectId      int64
	pubBookSelectOpenId  string
	leaveMsgSelectId     int64
	leaveMsgSelectOpenId string
}

func InitAppState() *AppState {
	return &AppState{}
}

func (a *AppState) GetIsLogin() bool {
	return a.isLogin
}

func (a *AppState) SetIsLogin(login bool) {
	a.isLogin = login
}

func (a *AppState) GetIsDoLogin() bool {
	return a.isDoLogin
}

func (a *AppState) SetIsDoLogin(login bool) {
	a.isDoLogin = login
}

func (a *AppState) GetIsDoUploadBook() bool {
	return a.isDoUploadBook
}

func (a *AppState) SetIsDoUploadBook(doUploadBook bool) {
	a.isDoUploadBook = doUploadBook
}

func (a *AppState) GetIsDoManageBook() bool {
	return a.isDoManageBook
}

func (a *AppState) SetIsDoManageBook(doManageBook bool) {
	a.isDoManageBook = doManageBook
}

func (a *AppState) GetIsDoLeaveMsg() bool {
	return a.isDoLeaveMsg
}

func (a *AppState) SetIsDoLeaveMsg(doLeaveMsg bool) {
	a.isDoLeaveMsg = doLeaveMsg
}

func (a *AppState) SetOpenId(openid string) {
	a.openId = openid
}

func (a *AppState) GetOpenId() string {
	return a.openId
}

func (a *AppState) SetNickName(nickName string) {
	a.nickName = nickName
}

func (a *AppState) GetNickName() string {
	return a.nickName
}

func (a *AppState) SetPubBooks(pubBooks []Book) {
	a.pubBooks = pubBooks
}

func (a *AppState) GetPubBooks() []Book {
	return a.pubBooks
}

func (a *AppState) SetMyBooks(myBooks []Book) {
	a.myBooks = myBooks
}

func (a *AppState) GetMyBooks() []Book {
	return a.myBooks
}

func (a *AppState) SetMyLeaveMsgs(msgs []LeaveMsg) {
	a.myLeaveMsgs = msgs
}

func (a *AppState) GetMyLeaveMsgs() []LeaveMsg {
	return a.myLeaveMsgs
}

func (a *AppState) SetListSelectId(id int) {
	a.listSelectId = id
}

func (a *AppState) GetListSelectId() int {
	return a.listSelectId
}

func (a *AppState) SetBookSelectId(id int64) {
	a.bookSelectId = id
}

func (a *AppState) GetBookSelectId() int64 {
	return a.bookSelectId
}

func (a *AppState) SetBookSelectOpenId(openid string) {
	a.bookSelectOpenId = openid
}

func (a *AppState) GetBookSelectOpenId() string {
	return a.bookSelectOpenId
}

func (a *AppState) SetPubBookSelectId(id int64) {
	a.pubBookSelectId = id
}

func (a *AppState) GetPubBookSelectId() int64 {
	return a.pubBookSelectId
}

func (a *AppState) SetPubBookSelectOpenId(openid string) {
	a.pubBookSelectOpenId = openid
}

func (a *AppState) GetPubBookSelectOpenId() string {
	return a.pubBookSelectOpenId
}

func (a *AppState) SetMyBookListLen(l int) {
	a.myBookListLen = l
}

func (a *AppState) GetMyBookListLen() int {
	return a.myBookListLen
}

func (a *AppState) SetLeaveMsgSelectId(id int64) {
	a.leaveMsgSelectId = id
}

func (a *AppState) GetLeaveMsgSelectId() int64 {
	return a.leaveMsgSelectId
}

func (a *AppState) SetLeaveMsgSelectOpenId(openid string) {
	a.leaveMsgSelectOpenId = openid
}

func (a *AppState) GetLeaveMsgSelectOpenId() string {
	return a.leaveMsgSelectOpenId
}

func init() {
	fontPath, err := findfont.Find("simkai.ttf")
	if err != nil {
		panic(err)
	}
	fmt.Printf("Found 'simkai.ttf' in '%s'\n", fontPath)
	fontData, err := os.ReadFile(fontPath)
	if err != nil {
		panic(err)
	}
	_, err = truetype.Parse(fontData)
	if err != nil {
		panic(err)
	}
	os.Setenv("FYNE_FONT", fontPath)
}

func main() {
	// ctx, cancel := context.WithCancel(context.Background())
	// defer cancel()
	a := app.New()
	w := a.NewWindow("Rabbit客户端")
	state := InitAppState()
	// 系统托盘
	makeTray(a, w)
	top := topView(a)
	center := centerView(a, state)
	right := rightView(a, state)
	bottom := bottomView(a)

	w.SetContent(container.NewBorder(top, bottom, nil, right, center))

	w.Resize(fyne.NewSize(600, 480))
	w.ShowAndRun()
}

// 系统托盘
func makeTray(a fyne.App, w fyne.Window) {
	if desk, ok := a.(desktop.App); ok {
		m := fyne.NewMenu("Rabbit", fyne.NewMenuItem("显示", func() {
			w.Show()
		}))
		desk.SetSystemTrayMenu(m)
	}
	w.SetCloseIntercept(func() {
		w.Hide()
	})
}

// topView 顶端视图
func topView(a fyne.App) fyne.CanvasObject {
	text := canvas.NewText("图 书 分 享 客 户 端", color.Black)
	text.TextSize = 24
	content := container.New(layout.NewCenterLayout(), text)
	return content
}

// 居中视图
func centerView(a fyne.App, state *AppState) fyne.CanvasObject {
	listData := getBookList(state, 1, 10)
	// 列表
	list := widget.NewTableWithHeaders(
		func() (int, int) {
			return len(listData), len(listData[0])
		},
		func() fyne.CanvasObject {
			return widget.NewLabel("")
		},
		func(i widget.TableCellID, o fyne.CanvasObject) {
			content := listData[i.Row][i.Col]
			l := utf8.RuneCountInString(content)
			if l > 10 {
				content = string([]rune(content)[:8]) + "..."
			}
			o.(*widget.Label).SetText(content)
		})

	list.CreateHeader = func() fyne.CanvasObject {
		l := widget.NewLabel("00")
		l.TextStyle.Bold = true
		l.Alignment = fyne.TextAlignLeading
		return l
	}
	list.UpdateHeader = func(id widget.TableCellID, template fyne.CanvasObject) {
		l := template.(*widget.Label)
		if id.Row < 0 {
			if id.Col == 0 {
				l.SetText("名称")
			}
			if id.Col == 1 {
				l.SetText("出版社")
			}
			if id.Col == 2 {
				l.SetText("ISBN")
			}
		} else if id.Col < 0 {
			l.SetText(strconv.Itoa(id.Row + 1))
		} else {
			l.SetText("")
		}
	}

	list.SetColumnWidth(0, 150)
	list.SetColumnWidth(1, 150)
	list.SetColumnWidth(2, 150)

	list.OnSelected = func(id widget.TableCellID) {
		log.Println("id,", id)
		row := id.Row
		pubBooks := state.GetPubBooks()
		bookId := pubBooks[row].Id
		openid := pubBooks[row].Openid
		log.Println("book.id", bookId, openid)
		state.SetPubBookSelectId(bookId)
		state.SetPubBookSelectOpenId(openid)
	}
	return list
}

// bottomView 底端视图
func bottomView(a fyne.App) fyne.CanvasObject {
	lbl1 := widget.NewLabel("关注【技术源泉】公众号了解更多详情！")
	content := container.New(layout.NewCenterLayout(), lbl1)
	return content
}

func rightView(a fyne.App, appState *AppState) fyne.CanvasObject {

	btn2 := widget.NewButton("上传", func() {
		doUploadBook(a, appState)
	})
	btn2.Disable()
	btn3 := widget.NewButton("我的图书", func() {
		doManageMyBook(a, appState)
	})
	btn3.Disable()
	btn4 := widget.NewButton("留言", func() {
		doLeaveMsg(a, appState)
	})
	btn4.Disable()
	btn5 := widget.NewButton("我的消息", func() {
		doGetLeaveMegs(a, appState)
	})
	btn5.Disable()

	// refreshBtn := widget.NewButton("刷新", func() {
	// 	doRefreshPubBooks()
	// })

	btn1 := widget.NewButton("登录", func() {
		isLogin := appState.GetIsLogin()
		if !isLogin {
			doLogin(a, appState, btn2, btn3, btn4, btn5)
		} else {
			doLogout(appState, btn2, btn3, btn4, btn5)
		}
	})

	btnGroup := container.New(layout.NewVBoxLayout(), layout.NewSpacer(), btn1, btn2, btn3, btn4, btn5, layout.NewSpacer())
	return btnGroup
}

// func doRefreshPubBooks() {
// getBookList()
// }

func doLogin(a fyne.App, appState *AppState, btn2 *widget.Button, btn3 *widget.Button, btn4 *widget.Button, btn5 *widget.Button) {
	isLogin := appState.GetIsLogin()
	isDoLogin := appState.GetIsDoLogin()
	if !isLogin {
		if !isDoLogin {
			appState.SetIsDoLogin(true)
			loginWindow := a.NewWindow("登录")
			// image := canvas.NewImageFromFile("./img/getcode.png")
			image := canvas.NewImageFromResource(resourceGetcodePng)
			image.SetMinSize(fyne.NewSize(200, 200))
			image.FillMode = canvas.ImageFillContain
			entry := widget.NewEntry()
			form := &widget.Form{
				SubmitText: "提交",
				Items: []*widget.FormItem{
					{Text: "验证码", Widget: entry},
				},
				OnSubmit: func() {
					vcode := entry.Text
					if vcode == "" {
						msg := dialog.NewInformation("提示", "验证码不能为空", loginWindow)
						msg.Show()
					} else {
						log.Println("form submitted:", vcode)
						ok := doHttpLogin(vcode, appState)
						if ok {
							appState.SetIsLogin(true)
							btn2.Enable()
							btn3.Enable()
							btn4.Enable()
							btn5.Enable()
							loginWindow.Close()

						} else {
							msg := dialog.NewInformation("提示", "验证码不正确", loginWindow)
							msg.Show()
						}
					}
				},
			}

			content := container.New(layout.NewVBoxLayout(), image, layout.NewSpacer(), form)
			loginWindow.SetContent(content)
			loginWindow.Resize(fyne.NewSize(320, 320))
			loginWindow.SetOnClosed(func() {
				appState.SetIsDoLogin(false)
			})
			loginWindow.Show()
		}
	}

}

func doUploadBook(a fyne.App, state *AppState) {
	isDoUploadBook := state.GetIsDoUploadBook()
	if !isDoUploadBook {
		state.SetIsDoUploadBook(true)
		uploadBookWindow := a.NewWindow("上传")
		nameEntry := widget.NewEntry()
		pressEntry := widget.NewEntry()
		isbnEntry := widget.NewEntry()
		form := &widget.Form{
			SubmitText: "提交",
			Items: []*widget.FormItem{
				{Text: "*名称", Widget: nameEntry},
				{Text: "*出版社", Widget: pressEntry},
				{Text: "*ISBN", Widget: isbnEntry},
			},
			OnSubmit: func() {
				name := nameEntry.Text
				press := pressEntry.Text
				isbn := isbnEntry.Text
				if name == "" || press == "" || isbn == "" {
					dialog.ShowInformation("提示", "*字段内容不能为空", uploadBookWindow)
				} else {
					log.Println("form submitted:", name, press, isbn)
					err := doHttpUploadBook(state, name, press, isbn)
					if err != nil {
						dialog.ShowError(err, uploadBookWindow)
					} else {
						dialog.ShowInformation("提示", "上传成功", uploadBookWindow)
					}
				}
			},
		}
		uploadBookWindow.SetContent(form)
		uploadBookWindow.Resize(fyne.NewSize(320, 280))
		uploadBookWindow.SetOnClosed(func() {
			state.SetIsDoUploadBook(false)
		})
		uploadBookWindow.Show()
	}
}

func doManageMyBook(a fyne.App, state *AppState) {
	isDoManageBook := state.GetIsDoManageBook()
	if !isDoManageBook {
		state.SetIsDoManageBook(true)
		myBookWindow := a.NewWindow("图书管理")
		myBookList := getMyBookList(state, 1, 10)
		log.Println("myBookList,", myBookList)
		state.SetMyBookListLen(len(myBookList))
		// 列表
		list := widget.NewTableWithHeaders(
			func() (int, int) {
				return len(myBookList), len(myBookList[0])
			},
			func() fyne.CanvasObject {
				return widget.NewLabel("")
			},
			func(i widget.TableCellID, o fyne.CanvasObject) {
				content := myBookList[i.Row][i.Col]
				l := utf8.RuneCountInString(content)
				if l > 10 {
					content = string([]rune(content)[:8]) + "..."
				}
				o.(*widget.Label).SetText(content)
			})
		list.SetColumnWidth(0, 120)
		list.SetColumnWidth(1, 120)
		list.SetColumnWidth(2, 120)
		list.SetColumnWidth(3, 120)
		list.CreateHeader = func() fyne.CanvasObject {
			l := widget.NewLabel("00")
			l.TextStyle.Bold = true
			l.Alignment = fyne.TextAlignLeading
			return l
		}
		list.UpdateHeader = func(id widget.TableCellID, template fyne.CanvasObject) {
			l := template.(*widget.Label)
			if id.Row < 0 {
				if id.Col == 0 {
					l.SetText("名称")
				}
				if id.Col == 1 {
					l.SetText("是否分享")
				}
				if id.Col == 2 {
					l.SetText("出版社")
				}
				if id.Col == 3 {
					l.SetText("ISBN")
				}

			} else if id.Col < 0 {
				l.SetText(strconv.Itoa(id.Row + 1))
			} else {
				l.SetText("")
			}
		}

		list.OnSelected = func(id widget.TableCellID) {
			log.Println("id,", id)
			row := id.Row
			pubBooks := state.GetMyBooks()
			bookId := pubBooks[row].Id
			openid := pubBooks[row].Openid
			state.SetListSelectId(row)
			state.SetBookSelectId(bookId)
			state.SetBookSelectOpenId(openid)
		}

		// list.Resize(fyne.NewSize(420, 320))

		shareBtn := widget.NewButton("分享", func() {
			lid := state.GetListSelectId()
			id := state.GetBookSelectId()
			openid := state.GetBookSelectOpenId()
			doShareBook(myBookWindow, list, myBookList, lid, openid, id)
		})

		deleteBtn := widget.NewButton("删除", func() {
			lid := state.GetListSelectId()
			id := state.GetBookSelectId()
			openid := state.GetBookSelectOpenId()
			myBookListLen := state.GetMyBookListLen()
			doDeleteBook(state, myBookWindow, list, myBookList, lid, openid, id, myBookListLen)
		})

		btnGrp := container.NewVBox(shareBtn, deleteBtn)
		content := container.NewBorder(nil, nil, nil, btnGrp, list)
		myBookWindow.SetContent(content)
		myBookWindow.Resize(fyne.NewSize(480, 320))
		myBookWindow.SetOnClosed(func() {
			state.SetIsDoManageBook(false)
		})

		myBookWindow.Show()
	}
}

func doShareBook(win fyne.Window, list *widget.Table, data [][]string, idx int, openid string, id int64) {
	err := doHttpShareBook(openid, id)
	if err != nil {
		dialog.ShowError(err, win)
		return
	}
	data[idx][1] = "已分享"
	list.Refresh()
	dialog.ShowInformation("提示", "分享成功", win)
}

func doDeleteBook(state *AppState, win fyne.Window, list *widget.Table, data [][]string, idx int, openid string, id int64, myBookListLen int) {
	err := doHttpDeleteBook(openid, id)
	if err != nil {
		dialog.ShowError(err, win)
		return
	}
	bookIdx := myBookListLen - 1
	state.SetMyBookListLen(bookIdx)
	l := len(data)
	log.Println("t1,", data, l, idx)
	if idx == bookIdx {
		data[bookIdx] = []string{"", "", "", ""}
	} else if idx == 0 {
		data = data[:copy(data, data[1:])]
		data[bookIdx] = []string{"", "", "", ""}
	} else {
		data = data[:idx+copy(data[idx:], data[idx+1:])]
		data[bookIdx] = []string{"", "", "", ""}
	}
	list.Refresh()
	dialog.ShowInformation("提示", "删除成功", win)
}

// 留言
func doLeaveMsg(a fyne.App, state *AppState) {
	leaveAMsg(a, state, 1)
}

// srcType 1 共享图书留言 2 我的消息回复留言
func leaveAMsg(a fyne.App, state *AppState, srcType int) {
	isDoLeaveMsg := state.GetIsDoLeaveMsg()
	if !isDoLeaveMsg {
		state.SetIsDoLeaveMsg(true)
		leaveMsgWindow := a.NewWindow("留言")
		msgEntry := widget.NewEntry()

		form := &widget.Form{
			SubmitText: "提交",
			Items: []*widget.FormItem{
				{Text: "*消息", Widget: msgEntry},
			},
			OnSubmit: func() {
				msg := msgEntry.Text
				if msg == "" {
					dialog.ShowInformation("提示", "*字段内容不能为空", leaveMsgWindow)
				} else {
					log.Println("form submitted:", msg)
					toopenid := ""
					switch srcType {
					case 1:
						toopenid = state.GetPubBookSelectOpenId()
					case 2:
						toopenid = state.GetLeaveMsgSelectOpenId()
					}
					if toopenid == "" {
						dialog.ShowError(errors.New("请选择图书记录"), leaveMsgWindow)
					} else {
						err := doHttpLeaveMsg(state.openId, toopenid, msg)
						if err != nil {
							dialog.ShowError(err, leaveMsgWindow)
						} else {
							dialog.ShowInformation("提示", "留言成功", leaveMsgWindow)
						}
					}
				}
			},
		}
		leaveMsgWindow.SetContent(form)
		leaveMsgWindow.Resize(fyne.NewSize(320, 280))
		leaveMsgWindow.SetOnClosed(func() {
			state.SetIsDoLeaveMsg(false)
		})
		leaveMsgWindow.Show()
	}
}

// 获取留言
func doGetLeaveMegs(a fyne.App, state *AppState) {
	data := getLeaveMsgList(state, 1, 10)

	log.Println("data3,", data)
	msgWindow := a.NewWindow("留言列表")
	list := widget.NewList(
		func() int {
			return len(data)
		},
		func() fyne.CanvasObject {
			return widget.NewLabel("")
		},
		func(i widget.ListItemID, o fyne.CanvasObject) {
			o.(*widget.Label).SetText(data[i])
		})
	list.OnSelected = func(id widget.ListItemID) {
		log.Println("列表id,", id)
		msgs := state.GetMyLeaveMsgs()
		lmId := msgs[id].Id
		lmOpenId := msgs[id].Openid
		state.SetLeaveMsgSelectId(lmId)
		state.SetLeaveMsgSelectOpenId(lmOpenId)
	}
	btnLeaveMsg := widget.NewButton("留言", func() {
		leaveAMsg(a, state, 2)
	})
	content := container.NewBorder(nil, btnLeaveMsg, nil, nil, list)
	msgWindow.SetContent(content)
	msgWindow.Resize(fyne.NewSize(480, 320))
	msgWindow.Show()
}

type CommonHttpResult struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}

type LoginHttpResult struct {
	CommonHttpResult
	Data UserInfo `json:"data"`
}

type UserInfo struct {
	Openid   string `json:"openid"`
	Nickname string `json:"nickname"`
}

// 登录
func doHttpLogin(vcode string, state *AppState) bool {
	resp, err := http.PostForm("https://libs.91demo.top/login1109",
		url.Values{"vcode": {vcode}})
	if err != nil {
		log.Println("http err,", err)
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
	}
	var result LoginHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
	}

	code := result.Code
	if code == 1 {
		log.Println("data,", result.Data)
		state.SetOpenId(result.Data.Openid)
		state.SetNickName(result.Data.Nickname)
		return true
	} else {
		log.Println("result err,", result.Msg)
	}
	return false
}

type BooksHttpResult struct {
	CommonHttpResult
	Data string `json:"data"`
}

type Book struct {
	Id         int64  `json:"id"`
	Openid     string `json:"openid"`
	Name       string `json:"name"`
	Press      string `json:"press"`
	Isbn       string `json:"isbn"`
	IsShare    int    `json:"isshare"`
	Status     int    `json:"status"`
	CreateTime int64  `json:"createtime"`
	UpdateTime int64  `json:"updatetime"`
}

// 获取图书列表
func getBookList(state *AppState, page int, pageSize int) [][]string {
	url := fmt.Sprintf("https://libs.91demo.top/getpubbooks?page=%d&page_size=%d", page, pageSize)
	resp, err := http.Get(url)
	if err != nil {
		log.Println("http err,", err)
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
	}
	var result BooksHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
	}

	code := result.Code
	if code == 1 {
		log.Println("data,", result.Data)
		var books []Book
		err = json.Unmarshal([]byte(result.Data), &books)
		if err != nil {
			log.Println("json2 err,", err)
		}
		state.SetPubBooks(books)
		bookArr := make([][]string, 0)
		blen := len(books)
		for i := 0; i < blen; i++ {
			book := make([]string, 0)
			name := strings.TrimSpace(books[i].Name)
			press := strings.TrimSpace(books[i].Press)
			isbn := strings.TrimSpace(books[i].Isbn)
			book = append(book, name)
			book = append(book, press)
			book = append(book, isbn)
			bookArr = append(bookArr, book)
		}
		return bookArr
	} else {
		log.Println("result err,", result.Msg)
	}
	return nil
}

func getMyBookList(state *AppState, page int, pageSize int) [][]string {
	url := fmt.Sprintf("https://libs.91demo.top/getmybooks?openid=%s&page=%d&page_size=%d", state.openId, page, pageSize)
	resp, err := http.Get(url)
	if err != nil {
		log.Println("http err,", err)
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
	}
	log.Println("data1,", string(body))
	var result BooksHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
	}

	code := result.Code
	if code == 1 {
		log.Println("data2,", result.Data)
		var books []Book
		err = json.Unmarshal([]byte(result.Data), &books)
		if err != nil {
			log.Println("json2 err,", err)
		}
		state.SetMyBooks(books)
		bookArr := make([][]string, 0)
		blen := len(books)
		for i := 0; i < blen; i++ {
			book := make([]string, 0)
			name := strings.TrimSpace(books[i].Name)
			press := strings.TrimSpace(books[i].Press)
			isbn := strings.TrimSpace(books[i].Isbn)
			isShare := books[i].IsShare
			isShareStr := "已分享"
			if isShare == 0 {
				isShareStr = "未分享"
			}
			book = append(book, name)
			book = append(book, isShareStr)
			book = append(book, press)
			book = append(book, isbn)
			bookArr = append(bookArr, book)
		}
		log.Println("bookArr,", bookArr)
		return bookArr
	} else {
		log.Println("result err,", result.Msg)
	}
	return nil
}

type LeaveMsgHttpResult struct {
	CommonHttpResult
	Data string `json:"data"`
}

type LeaveMsg struct {
	Id         int64
	Openid     string
	Name       string
	Msg        string
	CreateTime int64
}

func getLeaveMsgList(state *AppState, page int, pageSize int) []string {
	url := fmt.Sprintf("https://libs.91demo.top/getleavemsgs?openid=%s&page=%d&page_size=%d", state.openId, page, pageSize)
	resp, err := http.Get(url)
	if err != nil {
		log.Println("http err,", err)
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
	}
	log.Println("data1,", string(body))
	var result LeaveMsgHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
	}

	code := result.Code
	if code == 1 {
		log.Println("data2,", result.Data)
		var msgs []LeaveMsg
		err = json.Unmarshal([]byte(result.Data), &msgs)
		if err != nil {
			log.Println("json2 err,", err)
		}
		state.SetMyLeaveMsgs(msgs)
		msgArr := make([]string, 0)
		blen := len(msgs)
		for i := 0; i < blen; i++ {
			name := strings.TrimSpace(msgs[i].Name)
			msg := strings.TrimSpace(msgs[i].Msg)
			content := fmt.Sprintf("[%s]->%s", name, msg)
			msgArr = append(msgArr, content)
		}
		log.Println("msgArr,", msgArr)
		return msgArr
	} else {
		log.Println("result err,", result.Msg)
	}
	return nil
}

// 上传图书
func doHttpUploadBook(state *AppState, name string, press string, isbn string) error {
	resp, err := http.PostForm("https://libs.91demo.top/addmybook",
		url.Values{"openid": {state.openId}, "name": {name}, "press": {press}, "isbn": {isbn}})
	if err != nil {
		log.Println("http err,", err)
		return err
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
		return err
	}
	var result CommonHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
		return err
	}

	code := result.Code
	if code != 1 {
		log.Println("result err,", result.Msg)
		return errors.New(result.Msg)
	}
	return nil
}

func doHttpShareBook(openid string, id int64) error {
	url := fmt.Sprintf("https://libs.91demo.top/sharemybook/%s/%d", openid, id)
	resp, err := http.Post(url, "application/x-www-form-urlencoded", nil)
	if err != nil {
		log.Println("http err,", err)
		return err
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
		return err
	}

	var result CommonHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
		return err
	}

	code := result.Code
	if code != 1 {
		log.Println("result err,", result.Msg)
		return errors.New(result.Msg)
	}
	return nil
}

func doHttpDeleteBook(openid string, id int64) error {
	url := fmt.Sprintf("https://libs.91demo.top/deletemybook/%s/%d", openid, id)
	resp, err := http.Post(url, "application/x-www-form-urlencoded", nil)
	if err != nil {
		log.Println("http err,", err)
		return err
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
		return err
	}
	var result CommonHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
		return err
	}

	code := result.Code
	if code != 1 {
		log.Println("result err,", result.Msg)
		return errors.New(result.Msg)
	}
	return nil
}

func doHttpLeaveMsg(fromopenid string, toopenid string, message string) error {
	resp, err := http.PostForm("https://libs.91demo.top/leavemessage",
		url.Values{"fromopenid": {fromopenid}, "toopenid": {toopenid}, "message": {message}})
	if err != nil {
		log.Println("http err,", err)
		return err
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Println("io err,", err)
		return err
	}
	var result CommonHttpResult
	err = json.Unmarshal(body, &result)
	if err != nil {
		log.Println("json err,", err)
		return err
	}

	code := result.Code
	if code != 1 {
		log.Println("result err,", result.Msg)
		return errors.New(result.Msg)
	}
	return nil
}

func doLogout(appState *AppState, btn2 *widget.Button, btn3 *widget.Button, btn4 *widget.Button, btn5 *widget.Button) {
	appState.SetIsLogin(false)
	appState.SetOpenId("")
	btn2.Disable()
	btn3.Disable()
	btn4.Disable()
	btn5.Disable()
}
